package sp.whereru;

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

/**
 * This class uses the devices built in GPS or network features to obtain the user's current location
 * at the time in which it is requested.
 * 
 * @author Nick Luzzi
 * @version 1
 */
public class GPS {
	private double longitude;
	private double latitude;
	private boolean isGPSEnabled;
	private boolean isNetEnabled;
	private Activity activity;
	private Location location;
	private LocationManager manager;

	/**
	 * Constructor for this GPS object.
	 * @param act the activity for which the gps services will be provided
	 */
	public GPS(Activity act) {
		activity = act;              
	}

	/**
	 * This method allows this GPS object to request the new device location.
	 * @return True if a location was successfully obtained, false otherwise.
	 */
	public boolean getCoordinates() {
		location = null;
		if (isGPSEnabled) {
			manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
			location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		}
		else if (isNetEnabled) {
			manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
			location = manager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		}

		boolean result = false;
		if (location != null){
			latitude = location.getLatitude();
			longitude = location.getLongitude();
			result = true;
		}    
		return result;
	}    

	/**
	 * A public accessor method for the last obtained latitude coordinate of the device.
	 * @return A double representing the user's longitude coordinate value.
	 */
	public double getLastLongitude(){
		return longitude;
	}

	/**
	 * A public accessor method for the last obtained latitude coordinate of the device.
	 * @return A double representing the user's latitude coordinate value.
	 */
	public double getLastLatitude(){
		return latitude;
	}

	/**
	 * This method obtains the user's angle to North relative to a destination position.
	 * @param lat The destination latitude coordinate value.
	 * @param lon The destination's longitude coordinate value.
	 * @return A double representing the angle East of true North.
	 */
	public double angleToNorth(double lat, double lon){
		Location destination = new Location(isGPSEnabled? LocationManager.GPS_PROVIDER : LocationManager.NETWORK_PROVIDER);
		destination.setLatitude(lat);
		destination.setLongitude(lon);    	
		return location.bearingTo(destination);
	} 
	
	/**
	 * This method returns the devices bearing, based on GPS services,
	 * in degrees East of true North.
	 * @return A double representing the devices bearing in degrees East of true North.
	 */
	public double getAngleTrue(){
		double result = 0d;
		if(location != null && location.hasBearing())
			result = location.getBearing();
		return result;		   
	}

	/**
	 * This method is available to allow the location listener updates to stop
	 * whenever requested.
	 */
	public void stopGPS(){
		manager.removeUpdates(locationListener);
	}

	/**
	 * This method is available to allow the location listener to start receiving gps updates.
	 */
	public void startGPS(){
		manager = (LocationManager)activity.getSystemService(Context.LOCATION_SERVICE);
		try{
			isGPSEnabled = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
		}
		catch (Exception e){
			isGPSEnabled = false;
		}
		try{
			isNetEnabled = manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
		} 
		catch (Exception e) {
			isNetEnabled = false;
		}  
	}

	/**
	 * This is the LocationListener for this GPS object. It's 
	 */
	 private final LocationListener locationListener = new LocationListener() {
		 public void onLocationChanged(Location location) {
		 }

		 public void onProviderDisabled(String provider) {
		 }

		 public void onProviderEnabled(String provider) {
		 }

		 public void onStatusChanged(String provider, int status, Bundle extras) {
		 }
	 };
}